/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = rtp_core.h                                         */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/20 by songbb                               */
/*******************************************************************/

#ifndef __RTP_CORE_H_
#define __RTP_CORE_H_

#include <frreport_comm.h>
#include "frlist.h"
#include "frhash2.h"
#include "frstr.h"

#include "conntrack.h"
#include "module.h"
#include "frbyte_buffer.h"

typedef enum __em_rtp_stream_type {
    APM_RTP_STREAM_TYPE_UNKNOWN = 0,
    APM_RTP_STREAM_TYPE_RTP,                    /* 通过UDP传输的RTP标准协议(https://tools.ietf.org/html/rfc3550) */
    APM_RTP_STREAM_TYPE_TCPRTP,                 /* 通过TCP传输的RTP码流协议,在包头增加了4个字节(1个字节的magic number:0x24;1个字节的channel number;2个字节的RTP包长) */
    APM_RTP_STREAM_TYPE_TCPRTP_NONSTANDARD      /* 通过TCP传输的RTP码流协议(非标准),在包头增加了2个字节的RTP包长,注意会分片 */
} Rtp_stream_type;

/*
 * L7session_rtp 用于存放RTP私有的session数据，对应L7_session的p_session_private变量
 */
typedef struct __st_L7session_rtp
{
    Rtp_stream_type stream_type;        /* 码流的类型 */
    unsigned short us_skip_len;         /* 在分片过程中记录需要跳过的字节长度 */
    unsigned short us_pre_seq;          /* 上一帧的Sequence number */
    unsigned int ui_pre_timestamp;      /* 上一帧的Timestamp */
    char c_pre_is_marker;               /* 上一帧是否带marker标识 */
    unsigned int ui_frame_len;          /* 上一帧的完整的一帧的长度 */

    unsigned int ui_a_ip;               /* 假定的A的IP */
    unsigned short us_a_port;           /* 假定的A的端口 */
    unsigned int ui_b_ip;               /* 假定的B的IP */
    unsigned short us_b_port;           /* 假定的B的端口 */

    unsigned long ul_a2b_fbt;           /* first byte timestamp from a to b */
    unsigned long ul_a2b_bytes;         /* bytes of first frame from a to b */
    unsigned long ul_a2b_ffft;          /* first full frame timestamp from a to b */
    int i_a2b_is_ff;                    /* current frame is a full frame from a to b */
    long l_a2b_seq;                     /* sequence number of last packet from a to b */
    unsigned long ul_a2b_pluff;         /* count packets lost until first full frame from a to b */
    unsigned int ui_a2b_ppt;            /* RTP timestamp of previous packet*/

    unsigned long ul_b2a_fbt;           /* first byte timestamp from b to a */
    unsigned long ul_b2a_bytes;         /* bytes of first frame from b to a */
    unsigned long ul_b2a_ffft;          /* first full frame timestamp from b to a */
    int i_b2a_is_ff;                    /* current frame is a full frame from b to a */
    long l_b2a_seq;                     /* sequence number of last packet from b to a */
    unsigned long ul_b2a_pluff;         /* count packets lost until first full frame from b to a */
    unsigned int ui_b2a_ppt;            /* RTP timestamp of previous packet*/

    char c_skip_this_ct;                /* 这个ct不再做分析 */
} L7session_rtp;

/**
 * RTP私有结构体
 */
typedef struct __st_L7session_rtp_private
{
    L7session_rtp *p_st_sess;            /* session数据 */
    L7_session *p_st_session;             /* 指向父级的L7_session结构体 */
} L7session_rtp_private;

/**
 * 用于存储在detect过程中的中间数据
 */
typedef struct __st_rtp_detect_session
{
    Rtp_stream_type stream_type;        /* 码流的类型 */
    char c_detect_succ_count;           /* detect成功的次数 */
    unsigned short us_pre_payload_type; /* 上一帧的Payload type */
    unsigned short us_pre_seq;          /* 上一帧的Sequence number */
    unsigned int ui_pre_timestamp;      /* 上一帧的Timestamp */
    unsigned int ui_pre_ssrc;           /* 上一帧的Synchronization Source identifier */
    char c_pre_is_marker;               /* 上一帧是否带marker标识 */
    unsigned int ui_dst_ip;             /* 上一帧的目的IP */
    unsigned short us_dst_port;         /* 上一帧的目的端口 */
    unsigned short us_skip_len;         /* 在分片过程中记录需要跳过的字节长度 */
} Rtp_detect_session;

int rtp_detect(Conntrack *p_st_conn
            , Apm_packet *p_st_packet);

int rtp_analyze(Conntrack *p_st_conn
                , Apm_packet *p_st_packet
                , Frhash_header *p_st_hash_report);

int rtp_session_destory(void *p_st_session_private_in);

#endif
